
#ifndef __FLEXIBLE_BUTTON_H__
#define __FLEXIBLE_BUTTON_H__

#include "stdint.h"
#include "string.h"

typedef void (*flex_button_response_callback)(void*);

typedef enum
{
    FLEX_BTN_PRESS_DOWN = 0,
    FLEX_BTN_PRESS_CLICK,
    FLEX_BTN_PRESS_DOUBLE_CLICK,
    FLEX_BTN_PRESS_SHORT_START,
    FLEX_BTN_PRESS_SHORT_UP,
    FLEX_BTN_PRESS_LONG_START,
    FLEX_BTN_PRESS_LONG_UP,
    FLEX_BTN_PRESS_LONG_HOLD,
    FLEX_BTN_PRESS_LONG_HOLD_UP,
    FLEX_BTN_PRESS_MAX,
    FLEX_BTN_PRESS_NONE,
} flex_button_event_t;


typedef struct flex_button
{
    uint8_t pressed_logic_level : 1; /* need user to init */

    /**
     * @event
     * The event of button in flex_button_evnt_t enum list.
     * Automatically initialized to the default value FLEX_BTN_PRESS_NONE
     *                                      by 'flex_button_register' API.
    */
    uint8_t event               : 4;

    /**
     * @status
     * Used to record the status of the button 
     * Automatically initialized to the default value 0.
    */
    uint8_t status              : 3;
    uint16_t scan_cnt;  /* 默认值为0。用于记录按键扫描的次数 */
    uint16_t click_cnt; /* 默认值为0。用于记录按键点击的次数 */

    uint16_t debounce_tick;       	/**< 消抖时间（按键扫描周期次数） */   
    uint16_t click_start_tick;			 /**< 单击开始时间（扫描周期次数） */
    uint16_t short_press_start_tick;	/**< 短按开始时间（扫描周期次数） */
    uint16_t long_press_start_tick;	  /**< 长按开始时间（扫描周期次数） */
    uint16_t long_hold_start_tick;		 /**< 长时间按住开始时间（扫描周期次数） */

    uint8_t  (*usr_button_read)(void);
    flex_button_response_callback  cb;
    struct flex_button* next;
} flex_button_t;

#ifdef __cplusplus
extern "C" {
#endif

int8_t flex_button_register(flex_button_t *button);
flex_button_event_t flex_button_event_read(flex_button_t* button);
void flex_button_scan(void);

#ifdef __cplusplus
}
#endif  
#endif /* __FLEXIBLE_BUTTON_H__ */
